package controller

import (
	"encoding/json"
	"net/http"
	"server/models"
	"server/utils"
	"text/template"

	"github.com/gin-gonic/gin"
)

func AuthenticationPage(c *gin.Context) {
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	response := models.Response{}
	aliPan.Path = "/oauth/authorize"
	res, err := aliPan.GetAccessTokenPage()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	tmpl, err := template.New("index").Parse(res)
	if err != nil {
		c.String(http.StatusInternalServerError, "Internal Server Error")
		return
	}
	// 创建一个字节数组，用于存储模板执行后的HTML内容
	var resultHTMLBytes []byte
	// 使用Execute方法将模板执行，并将结果写入resultHTMLBytes
	err = tmpl.Execute(c.Writer, nil)
	if err != nil {
		c.String(http.StatusInternalServerError, "Internal Server Error")
		return
	}
	// c.JSON(http.StatusOK, response)
	// 将结果HTML内容写入响应
	c.Data(http.StatusOK, "text/html; charset=utf-8", resultHTMLBytes)
}

func AuthenticationCode(c *gin.Context) {
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	response := models.Response{}
	aliPan.Path = "/oauth/authorize"
	res, err := aliPan.GetAccessTokenCode()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	c.JSON(http.StatusOK, response)
}

func Authentication(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	aliPan.Path = "/oauth/access_token"
	res, err := aliPan.GetAccessToken()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	c.JSON(http.StatusOK, response)
}

func RefreshAuthentication(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	aliPan.Path = "/oauth/access_token"
	res, err := aliPan.RefreshAuthentication()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	c.JSON(http.StatusOK, response)
}

func GetUserInfo(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host: utils.Application.Alipan.Host,
		Path: "/oauth/users/info",
	}
	res, err := aliPan.GetUserInfo()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	c.JSON(http.StatusOK, response)
}

func GetOpenFileList(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host: utils.Application.Alipan.Host,
		Path: "/adrive/v1.0/openFile/list",
	}
	// 传两个参数 file_id, drive_id

	query := c.Request.URL.Query()
	var queryMap = make(map[string]interface{}, len(query))
	for k := range query {
		queryMap[k] = c.Query(k)
	}

	res, err := aliPan.GetOpenFileList(queryMap, utils.Application.Alipan.PasswordFileName)
	if res == "405" {
		response.Code = 405
		response.Msg = "查看该文件夹需要密码"
		c.JSON(http.StatusOK, response)
		return
	}
	// 将json传转map
	var jsonMap map[string]interface{}
	if err := json.Unmarshal([]byte(res), &jsonMap); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse JSON"})
		return
	}
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = jsonMap
	}
	c.JSON(http.StatusOK, response)
}

func GetUserInfoScopes(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		Path:         "/oauth/users/scopes",
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	res, err := aliPan.GetUserInfoScopes()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	c.JSON(http.StatusOK, response)
}

func GetAuthQrcode(c *gin.Context) {
	response := models.Response{}
	var aliPan = &models.AliPan{
		Host:         utils.Application.Alipan.Host,
		Path:         "/oauth/authorize/qrcode",
		ClientId:     utils.Application.Alipan.ClientId,
		ClientSecret: utils.Application.Alipan.ClientSecret,
	}
	res, sid, err := aliPan.GetAuthQrcode()
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = res
	}
	cookie, err := c.Cookie("sid")
	// 为客户端种cookie
	// 3分钟过期，因此需要设置cookie三分钟失效
	if err != nil || cookie != sid {
		// cookie = "NoSet"
		//Cookie名称、Cookie值、过期时间（秒）、路径、域名、是否只能通过HTTPS传输、是否禁止JavaScript访问
		c.SetCookie("sid", sid, 180, "/", "localhost", false, true)
	}
	c.Header("Content-Type", "application/octet-stream")
	// 设置文件名
	c.Header("Content-Disposition", "attachment; filename=qrcode.bin")
	c.Data(http.StatusOK, "application/octet-stream", res.Body())
}

func GetAuthQrcodeStatus(c *gin.Context) {
	response := models.Response{}
	cookie, err := c.Cookie("sid")
	if err != nil {
		response.Msg = "cookie not found"
	}
	var aliPan = &models.AliPan{
		Host: utils.Application.Alipan.Host,
		Path: "/oauth/qrcode/" + cookie + "/status",
	}
	res, err := aliPan.GetAuthQrcodeStatus()
	var jsonMap map[string]interface{}
	if err := json.Unmarshal([]byte(res), &jsonMap); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse JSON"})
		return
	}
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = jsonMap
	}
	c.JSON(http.StatusOK, response)
}

func GetFileDetailById(c *gin.Context) {
	response := models.Response{}
	m := make(map[string]interface{})
	c.BindJSON(&m)
	var aliPan = &models.AliPan{
		Host: utils.Application.Alipan.Host,
		Path: "/adrive/v1.0/openFile/get",
	}
	res, err := aliPan.GetFileDetailById(m)
	var jsonMap map[string]interface{}
	if err := json.Unmarshal([]byte(res), &jsonMap); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse JSON"})
		return
	}
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = jsonMap
	}
	c.JSON(http.StatusOK, response)
}

func GetFileDownload(c *gin.Context) {
	response := models.Response{}
	m := make(map[string]interface{})
	c.BindJSON(&m)
	var aliPan = &models.AliPan{
		Host: utils.Application.Alipan.Host,
		Path: "/adrive/v1.0/openFile/getDownloadUrl",
	}
	res, err := aliPan.GetFileDownloadLogic(m)
	var jsonMap map[string]interface{}
	if err := json.Unmarshal([]byte(res), &jsonMap); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse JSON"})
		return
	}
	if err != nil {
		response.Code = ERR
		response.Msg = "failed"
		response.Data = err
	} else {
		response.Code = SUCC
		response.Msg = "success"
		response.Data = jsonMap
	}
	c.JSON(http.StatusOK, response)
}
